/*
 * Copyright the original author or authors.
 * 
 * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.mozilla.org/MPL/MPL-1.1.html
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.babeuf.form.messages 
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.net.URLLoader;
	import flash.utils.Dictionary;
	import net.babeuf.form.event.MessagesEvent;
	import net.babeuf.form.fields.AbstractField;
	/**
	 * ...
	 * @author damien pegoraro
	 */
	public class Messages extends EventDispatcher
	{
		/**
		* Dispatched when an external messages file has been loaded successfully
		* @eventType net.babeuf.form.event.MessagesEvent.MESSAGES_LOADED
		*/
		[Event(name="messagesLoaded", type="net.babeuf.form.event.MessagesEvent")]
		
		
		public static const FIELD_NAME : String = "%%FIELD%%" ; 	
		
		public static const DEFAULT : String = "default" ; 
		public static const GENERIC_MIN : String = "min" ; 
		public static const GENERIC_MAX : String = "max" ; 
		public static const GENERIC_EMPTY : String = "empty" ; 
		public static const GENERIC_INVALID : String = "invalid" ; 
		
		protected var _messages : Dictionary ; 
		protected var _loader : URLLoader ; 
		
		
		public function Messages() 
		{
			_messages = new Dictionary( true ) ; 
			_messages[DEFAULT] = "There's an error in field " + FIELD_NAME ; 
			_messages[GENERIC_MIN] = "The field " + FIELD_NAME + " is too small." ; 
			_messages[GENERIC_MAX] = "The field " + FIELD_NAME + " is too large." ; 
			_messages[GENERIC_EMPTY] = "The field " + FIELD_NAME + " must be filled." ; 
			_messages[GENERIC_INVALID] = "The field " + FIELD_NAME + " is not valid." ; 
		}
		
		public function add(id : String, message : String ) : void
		{
			_messages[id] = message ; 
		}
		
		public function initFromXML( xml : XML ) : void
		{			
			parseNode("", xml, true) ; 
		}
		
		public function initFromFile( url : String ) : void
		{
			_loader = new URLLoader() ; 
			_loader.addEventListener(Event.COMPLETE, fileLoaded) ; 
		}
		
		private function fileLoaded(e:Event):void 
		{
			initFromXML( new XML( e.target.data ) ) ; 
			dispatchEvent( new MessagesEvent( MessagesEvent.MESSAGES_LOADED) ) ; 
		}
		
		private function parseNode( prefix : String, node : XML, first : Boolean = false ) : void 
		{			
			if ( !first )  prefix  = prefix +  (prefix.length == 0 ? "" : ".") + node.localName() ; 
			
			if ( node.elements() && node.elements().length() == 0 ) 
			{
				add(prefix,node.toString().split("\r\n").join("\n")) ;				
			}
			else
			{
				for each ( var child : XML in node.elements() ) 
				{
					parseNode( prefix, child ) ; 					
				}				
			}
		}
		
		public function get( id : String, field : AbstractField = null ) : String
		{
			var out : String  ; 			
			if ( _messages[id] ) out = _messages[id] ; 
			else out = _messages[DEFAULT] ; 
			return _formatMessage( out, field ) ; 
		}
		
		protected function _formatMessage( message : String, field : AbstractField = null  ) : String
		{
			if ( !field ) return message ; 
			message = message.split(FIELD_NAME).join(field.name) ; 
			return message ; 
		}
		
		public function dispose() : void
		{
			if ( _loader )
			{
				_loader.removeEventListener(Event.COMPLETE, fileLoaded) ; 
				try { _loader.close() ;  } catch ( e : Error ) { } ; 
			}
			
			_loader = null ; 
		}
		
		
	}

}